
use super::BackupResult;
use super::BackupStatistics;
use super::ExtractorProduct;
use crate::recipe::ChunkPointer;
use parking_lot::Mutex;
use pipelines::{Sender,Receiver};

use std::fmt::Debug;
use std::sync::Arc;
use std::time::Instant;

pub struct ChunkTestor {
    statistics:Arc<Mutex<BackupStatistics>>,
}

impl ChunkTestor {
    pub fn new(statistics:Arc<Mutex<BackupStatistics>>) -> Self {
        Self {
            statistics:statistics,
        }
    }
    
    pub fn test<P:ChunkPointer+Debug+Send>(&self,out:&Sender<ExtractorProduct<P>>,recv:Receiver<ExtractorProduct<P>>) -> BackupResult<()> {
        let mut gear_hash_time:u128 = 0;
        let mut pack_feature_time:u128 = 0;
        let mut odess_sample_num:usize = 0;
        let mut odess_sample_recoder:OdessSampleRecorder = OdessSampleRecorder::new();
        for product in recv {
            match product {
                ExtractorProduct::FileInfo(info) => {
                    out.send(ExtractorProduct::FileInfo(info));
                }
                ExtractorProduct::ChunkPointer(chunk_pointer) => {
                    out.send(ExtractorProduct::ChunkPointer(chunk_pointer));
                },
                ExtractorProduct::Chunk(chunk) => {
                    let mut sf = superfeature::super_feature::SuperFeature::new();
                    let now = Instant::now();
                    let sample_num = sf.test_gear_roll(&chunk as &[u8]);
                    gear_hash_time += now.elapsed().as_micros();
                    odess_sample_num = std::cmp::max(odess_sample_num, sample_num);

                    let now = Instant::now();
                    sf.test_pack_feature();
                    pack_feature_time += now.elapsed().as_micros();
                    odess_sample_recoder.record((&chunk as &[u8]).len(), sample_num);
                    out.send(ExtractorProduct::Chunk(chunk));
                },
            }
        }
        self.statistics.lock().set_gear_hash_time(gear_hash_time);
        self.statistics.lock().set_pack_feature_time(pack_feature_time);
        self.statistics.lock().set_odess_sample_time(odess_sample_num);
        Ok(())
    }
}

#[derive(Clone, Copy)]
pub struct OdessSampleRecorder {

}

impl OdessSampleRecorder {
    pub fn new() -> Self {
        Self {}
    }

    pub fn record(&mut self, len:usize, num:usize) {
        let _ = len;
        let _ = num;
    }
}

impl std::fmt::Display for OdessSampleRecorder {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		let output = format!("unsupported");
		write!(f,"{}",output)
	}
}


